View Javadoc

1   /*
2    * TouchGraph LLC. Apache-Style Software License
3    *
4    *
5    * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved.
6    *
7    * Redistribution and use in source and binary forms, with or without
8    * modification, are permitted provided that the following conditions
9    * are met:
10   *
11   * 1. Redistributions of source code must retain the above copyright
12   *    notice, this list of conditions and the following disclaimer. 
13   *
14   * 2. Redistributions in binary form must reproduce the above copyright
15   *    notice, this list of conditions and the following disclaimer in
16   *    the documentation and/or other materials provided with the
17   *    distribution.
18   *
19   * 3. The end-user documentation included with the redistribution,
20   *    if any, must include the following acknowledgment:  
21   *       "This product includes software developed by 
22   *        TouchGraph LLC (http://www.touchgraph.com/)."
23   *    Alternately, this acknowledgment may appear in the software itself,
24   *    if and wherever such third-party acknowledgments normally appear.
25   *
26   * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse 
27   *    or promote products derived from this software without prior written 
28   *    permission.  For written permission, please contact 
29   *    alex@touchgraph.com
30   *
31   * 5. Products derived from this software may not be called "TouchGraph",
32   *    nor may "TouchGraph" appear in their name, without prior written
33   *    permission of alex@touchgraph.com.
34   *
35   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38   * DISCLAIMED.  IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE 
39   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
40   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
41   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
42   * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
43   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
44   * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
45   * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46   * ====================================================================
47   *
48   */
49  
50  package com.touchgraph.graphlayout;
51  
52  import java.awt.*;
53  import java.awt.event.*;
54  import java.util.Hashtable;
55  
56  import javax.swing.*;
57  
58  import com.touchgraph.graphlayout.interaction.*;
59  
60  /*** GLPanel contains code for adding scrollbars and interfaces to the TGPanel
61    * The "GL" prefix indicates that this class is GraphLayout specific, and
62    * will probably need to be rewritten for other applications.
63    *
64    * @author   Alexander Shapiro
65    * @version  1.21  $Id: GLPanel.java,v 1.1.1.1 2004/02/06 08:44:05 keesj Exp $
66    */
67  public class GLPanel extends JPanel {
68  
69      public String zoomLabel = "Zoom"; // label for zoom menu item
70      public String rotateLabel = "Rotate"; // label for rotate menu item
71      public String localityLabel = "Locality"; // label for locality menu item
72  
73      public HVScroll hvScroll;
74      public ZoomScroll zoomScroll;
75      //public HyperScroll hyperScroll; // unused
76      public RotateScroll rotateScroll;
77      public LocalityScroll localityScroll;
78      public JPopupMenu glPopup;
79      public Hashtable scrollBarHash; //= new Hashtable();
80  
81      protected TGPanel tgPanel;
82      protected TGLensSet tgLensSet;
83      protected TGUIManager tgUIManager;
84  
85      private Color defaultColor = Color.lightGray;
86  
87    // ............
88  
89  
90     /*** Default constructor.
91       */
92      public GLPanel() {
93          scrollBarHash = new Hashtable();
94          tgLensSet = new TGLensSet();
95          tgPanel = new TGPanel();
96          hvScroll = new HVScroll(tgPanel, tgLensSet);
97          zoomScroll = new ZoomScroll(tgPanel);
98        //hyperScroll = new HyperScroll(tgPanel);
99          rotateScroll = new RotateScroll(tgPanel);
100         localityScroll = new LocalityScroll(tgPanel);
101         initialize();
102     }
103 
104 
105    /*** Constructor with a Color to be used for UI background.
106      */
107     public GLPanel( Color color ) {
108         defaultColor = color;
109         this.setBackground(color);
110         scrollBarHash = new Hashtable();
111         tgLensSet = new TGLensSet();
112         tgPanel = new TGPanel();
113         tgPanel.setBackground(color);
114         hvScroll = new HVScroll(tgPanel, tgLensSet);
115       //hvScroll.getHorizontalSB().setBackground(Color.orange);
116       //hvScroll.getVerticalSB().setBackground(Color.cyan);
117         zoomScroll = new ZoomScroll(tgPanel);
118       //zoomScroll.getZoomSB().setBackground(Color.green);
119       //hyperScroll = new HyperScroll(tgPanel);
120         rotateScroll = new RotateScroll(tgPanel);
121       //rotateScroll.getRotateSB().setBackground(Color.blue);
122         localityScroll = new LocalityScroll(tgPanel);
123       //localityScroll.getLocalitySB().setBackground(Color.red);
124         initialize();
125     }
126 
127 
128    /*** Initialize panel, lens, and establish a random graph as a demonstration.
129      */
130     public void initialize() {
131         buildPanel();
132         buildLens();
133         tgPanel.setLensSet(tgLensSet);
134         addUIs();
135       //tgPanel.addNode();  //Add a starting node.
136      /*   try {
137             randomGraph();
138         } catch ( TGException tge ) {
139             System.err.println(tge.getMessage());
140             tge.printStackTrace(System.err);
141         }
142         */
143 
144         setVisible(true);
145     }
146 
147     /*** Return the TGPanel used with this GLPanel. */
148     public TGPanel getTGPanel() {
149         return tgPanel;
150     }
151 
152   // navigation .................
153 
154     /*** Return the HVScroll used with this GLPanel. */
155     public HVScroll getHVScroll()
156     {
157         return hvScroll;
158     }
159 
160     ///*** Return the HyperScroll used with this GLPanel. */
161     //public HyperScroll getHyperScroll()
162     //{
163     //    return hyperScroll;
164     //}
165 
166     /*** Sets the horizontal offset to p.x, and the vertical offset to p.y
167       * given a Point <tt>p<tt>. 
168       */
169     public void setOffset( Point p ) {
170         hvScroll.setOffset(p);
171     };
172 
173     /*** Return the horizontal and vertical offset position as a Point. */
174     public Point getOffset() {
175         return hvScroll.getOffset();
176     };
177 
178   // rotation ...................
179 
180     /*** Return the RotateScroll used with this GLPanel. */
181     public RotateScroll getRotateScroll()
182     {
183         return rotateScroll;
184     }
185 
186     /*** Set the rotation angle of this GLPanel (allowable values between 0 to 359). */
187      public void setRotationAngle( int angle ) {
188         rotateScroll.setRotationAngle(angle);
189     }
190 
191     /*** Return the rotation angle of this GLPanel. */
192     public int getRotationAngle() {
193         return rotateScroll.getRotationAngle();
194     }
195 
196   // locality ...................
197 
198     /*** Return the LocalityScroll used with this GLPanel. */
199     public LocalityScroll getLocalityScroll()
200     {
201         return localityScroll;
202     }
203 
204     /*** Set the locality radius of this TGScrollPane  
205       * (allowable values between 0 to 4, or LocalityUtils.INFINITE_LOCALITY_RADIUS). 
206       */
207     public void setLocalityRadius( int radius ) {
208         localityScroll.setLocalityRadius(radius);
209     }
210 
211     /*** Return the locality radius of this GLPanel. */
212     public int getLocalityRadius() {
213         return localityScroll.getLocalityRadius();
214     }
215 
216   // zoom .......................
217 
218     /*** Return the ZoomScroll used with this GLPanel. */
219     public ZoomScroll getZoomScroll() 
220     {
221         return zoomScroll;
222     }
223 
224     /*** Set the zoom value of this GLPanel (allowable values between -100 to 100). */
225     public void setZoomValue( int zoomValue ) {
226         zoomScroll.setZoomValue(zoomValue);
227     }
228 
229     /*** Return the zoom value of this GLPanel. */
230     public int getZoomValue() {
231         return zoomScroll.getZoomValue();
232     }
233 
234   // ....
235 
236     public JPopupMenu getGLPopup() 
237     {
238         return glPopup;
239     }
240 
241     public void buildLens() {
242         tgLensSet.addLens(hvScroll.getLens());
243         tgLensSet.addLens(zoomScroll.getLens());
244       //tgLensSet.addLens(hyperScroll.getLens());
245         tgLensSet.addLens(rotateScroll.getLens());
246         tgLensSet.addLens(tgPanel.getAdjustOriginLens());
247     }
248 
249     public void buildPanel() {
250         final JScrollBar horizontalSB = hvScroll.getHorizontalSB();
251         final JScrollBar verticalSB = hvScroll.getVerticalSB();
252         final JScrollBar zoomSB = zoomScroll.getZoomSB();
253         final JScrollBar rotateSB = rotateScroll.getRotateSB();
254         final JScrollBar localitySB = localityScroll.getLocalitySB();
255 
256         setLayout(new BorderLayout());
257 
258         JPanel scrollPanel = new JPanel();
259         scrollPanel.setBackground(defaultColor);
260         scrollPanel.setLayout(new GridBagLayout());
261         GridBagConstraints c = new GridBagConstraints();
262 
263 
264         JPanel modeSelectPanel = new JPanel();
265         modeSelectPanel.setBackground(defaultColor);
266         modeSelectPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 0,0));
267 
268         AbstractAction navigateAction = new AbstractAction("Navigate") {
269             public void actionPerformed(ActionEvent e) {
270                 tgUIManager.activate("Navigate");
271             }
272         };
273 
274         AbstractAction editAction = new AbstractAction("Edit") {
275             public void actionPerformed(ActionEvent e) {
276                 tgUIManager.activate("Edit");
277             }
278         };
279 
280         JRadioButton rbNavigate = new JRadioButton(navigateAction);
281         rbNavigate.setBackground(defaultColor);
282         rbNavigate.setSelected(true);
283         JRadioButton rbEdit = new JRadioButton(editAction);
284         rbEdit.setBackground(defaultColor);
285         ButtonGroup bg = new ButtonGroup();
286         bg.add(rbNavigate);
287         bg.add(rbEdit);
288 
289         modeSelectPanel.add(rbNavigate);
290         modeSelectPanel.add(rbEdit);
291 
292         //final JPanel topPanel = new JPanel();
293         final JToolBar topPanel = new JToolBar();
294         topPanel.setBackground(defaultColor);
295         topPanel.setLayout(new GridBagLayout());
296         c.gridy=0; c.fill=GridBagConstraints.HORIZONTAL;
297         /*
298         c.gridx=0;c.weightx=0;
299         topPanel.add(new Label("Zoom",Label.RIGHT), c);
300         c.gridx=1;c.weightx=0.5;
301         topPanel.add(zoomSB,c);
302         c.gridx=2;c.weightx=0;
303         topPanel.add(new Label("Locality",Label.RIGHT), c);
304         c.gridx=3;c.weightx=0.5;
305         topPanel.add(localitySB,c);
306         */
307         c.gridx=0;c.weightx=0;c.insets = new Insets(0,10,0,10);
308         topPanel.add(modeSelectPanel,c);
309         c.insets=new Insets(0,0,0,0);
310         c.gridx=1;c.weightx=1;
311 
312         scrollBarHash.put(zoomLabel, zoomSB);
313         scrollBarHash.put(rotateLabel, rotateSB);
314         scrollBarHash.put(localityLabel, localitySB);
315 
316         JPanel scrollselect = scrollSelectPanel(new String[] {zoomLabel, rotateLabel, localityLabel});
317         scrollselect.setBackground(defaultColor);
318         topPanel.add(scrollselect,c);
319 
320         add(topPanel, BorderLayout.NORTH);
321 
322         c.fill = GridBagConstraints.BOTH;
323         c.gridwidth = 1;
324         c.gridx = 0; c.gridy = 1; c.weightx = 1; c.weighty = 1;
325         scrollPanel.add(tgPanel,c);
326 
327         c.gridx = 1; c.gridy = 1; c.weightx = 0; c.weighty = 0;
328         scrollPanel.add(verticalSB,c);
329 
330         c.gridx = 0; c.gridy = 2;
331         scrollPanel.add(horizontalSB,c);
332 
333         add(scrollPanel,BorderLayout.CENTER);
334 
335         glPopup = new JPopupMenu();
336         glPopup.setBackground(defaultColor);
337 
338         JMenuItem menuItem = new JMenuItem("Toggle Controls");
339         ActionListener toggleControlsAction = new ActionListener() {
340                 boolean controlsVisible = true;
341                 public void actionPerformed(ActionEvent e) {
342                     controlsVisible = !controlsVisible;
343                     horizontalSB.setVisible(controlsVisible);
344                     verticalSB.setVisible(controlsVisible);
345                     topPanel.setVisible(controlsVisible);
346                 }
347             };
348         menuItem.addActionListener(toggleControlsAction);
349         glPopup.add(menuItem);
350     }
351 
352     protected JPanel scrollSelectPanel(String[] scrollBarNames) {
353         final JComboBox scrollCombo = new JComboBox(scrollBarNames);
354         scrollCombo.setBackground(defaultColor);
355         scrollCombo.setPreferredSize(new Dimension(80,20));
356         scrollCombo.setSelectedIndex(0);
357         final JScrollBar initialSB = (JScrollBar) scrollBarHash.get(scrollBarNames[0]);
358         scrollCombo.addActionListener(new ActionListener() {
359             JScrollBar currentSB = initialSB;
360             public void actionPerformed(ActionEvent e) {
361                 JScrollBar selectedSB = (JScrollBar) scrollBarHash.get(
362                         (String) scrollCombo.getSelectedItem());
363                 if (currentSB!=null) currentSB.setVisible(false);
364                 if (selectedSB!=null) selectedSB.setVisible(true);
365                 currentSB = selectedSB;
366             }
367         });
368 
369         final JPanel sbp = new JPanel(new GridBagLayout());
370         sbp.setBackground(defaultColor);
371         GridBagConstraints c = new GridBagConstraints();
372         c.gridx = 0; c.gridy = 0; c.weightx= 0;
373         sbp.add(scrollCombo,c);
374         c.gridx = 1; c.gridy = 0; c.weightx = 1; c.insets=new Insets(0,10,0,17);
375         c.fill=GridBagConstraints.HORIZONTAL;
376         for (int i = 0;i<scrollBarNames.length;i++) {
377             JScrollBar sb = (JScrollBar) scrollBarHash.get(scrollBarNames[i]);
378               if(sb==null) continue;
379               if(i!=0) sb.setVisible(false);
380               //sb.setMinimumSize(new Dimension(200,17));
381               sbp.add(sb,c);
382         }
383         return sbp;
384     }
385 
386     public void addUIs() {
387         tgUIManager = new TGUIManager();
388         GLEditUI editUI = new GLEditUI(this);
389         GLNavigateUI navigateUI = new GLNavigateUI(this);
390         tgUIManager.addUI(editUI,"Edit");
391         tgUIManager.addUI(navigateUI,"Navigate");
392         tgUIManager.activate("Navigate");
393     }
394 
395     public void randomGraph() throws TGException {
396         Node n1= tgPanel.addNode();
397         n1.setType(0);
398         for ( int i=0; i<249; i++ ) {
399             Node r = tgPanel.getGES().getRandomNode();
400             Node n = tgPanel.addNode();
401             n.setType(0);
402             if (tgPanel.findEdge(r,n)==null) tgPanel.addEdge(r,n,Edge.DEFAULT_LENGTH);
403             if (i%2==0) {
404                 r = tgPanel.getGES().getRandomNode();
405                 if (tgPanel.findEdge(r,n)==null) tgPanel.addEdge(r,n,Edge.DEFAULT_LENGTH);
406             }
407         }
408         tgPanel.setLocale(n1,2);
409     }    
410 
411     public static void main(String[] args) {
412 
413         JFrame frame;
414         frame = new JFrame("Graph Layout");
415         GLPanel glPanel = new GLPanel();
416         frame.addWindowListener(new WindowAdapter() {
417             public void windowClosing(WindowEvent e) {System.exit(0);}
418         });
419 
420         frame.getContentPane().add("Center", glPanel);
421         frame.setSize(500,500);
422         frame.setVisible(true);
423     }
424 
425 } // end com.touchgraph.graphlayout.GLPanel